package com.example.mobilesafe.activity;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.format.Formatter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.example.mobilesafe.R;
import com.example.mobilesafe.constant.ConstantValue;
import com.example.mobilesafe.dao.ProcessInfoDao;
import com.example.mobilesafe.domain.ProcessInfo;
import com.example.mobilesafe.utils.SharedPreferencesUtil;
import com.example.mobilesafe.utils.ToastUtil;

import java.util.ArrayList;
import java.util.List;

public class ProcessManagerActivity extends AppCompatActivity {

    private TextView tv_process_count;

    private TextView tv_memory_info;

    private TextView tv_title_type;

    private ListView lv_process_list;

    private Button btn_all;

    private Button btn_reverse;

    private Button btn_clear;

    private Button btn_setting;

    private int mProcessCount; // 进程总数

    private List<ProcessInfo> mProcessInfoList;

    private List<ProcessInfo> mSystemList;

    private List<ProcessInfo> mCustomerList;

    private MyAdapter mAdapter;

    private ProcessInfo mProcessInfo;

    private long mAvailSpace;

    private long mTotalSpace;

    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            mAdapter = new MyAdapter();
            lv_process_list.setAdapter(mAdapter);
            if (tv_title_type != null && mCustomerList != null ){
                tv_title_type.setText("用户进程("+mCustomerList.size()+")");
            }
        }
    };

    class MyAdapter extends BaseAdapter {

        // 在ListView中多添加一种类型条目，条目总数有2种
        @Override
        public int getViewTypeCount() {
            return super.getViewTypeCount() + 1;
        }

        // 根据索引值决定展示哪种类型的条目
        @Override
        public int getItemViewType(int position) {
            if (position == 0 || position == mCustomerList.size() + 1){
                // 纯文本条目
                return 0;
            }else {
                // 图文条目
                return 1;
            }
        }

        @Override
        public int getCount() {
            if (SharedPreferencesUtil.getBoolean(getApplicationContext(), ConstantValue.SHOW_SYSTEM,false)){
                return mCustomerList.size() + mSystemList.size() + 2;
            }else {
                return mCustomerList.size() + 1;
            }
        }

        @Override
        public ProcessInfo getItem(int position) {
            if (position == 0 || position == mCustomerList.size() + 1){
                // 纯文本条目
                return null;
            }else {
                // 图文条目
                if (position < mCustomerList.size() + 1){
                    // 用户应用
                    return mCustomerList.get(position - 1);
                }else {
                    // 系统应用
                    return mSystemList.get(position - mCustomerList.size() - 2);
                }
            }
            // return mAppInfoList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            // 判断当前索引指向的条目类型状态码
            int itemViewType = getItemViewType(position);
            if (itemViewType == 0){
                // 纯文本条目
                ViewTitleHolder holder = null;
                if (convertView == null){
                    convertView = View.inflate(getApplicationContext(),R.layout.list_app_item_text,null);
                    holder = new ViewTitleHolder();
                    holder.tv_title_des = convertView.findViewById(R.id.tv_title_des);
                    convertView.setTag(holder);
                }else {
                    holder = (ViewTitleHolder) convertView.getTag();
                }
                if (position == 0){
                    holder.tv_title_des.setText("用户进程("+mCustomerList.size()+")");
                }else {
                    holder.tv_title_des.setText("系统进程("+mSystemList.size()+")");
                }
                return convertView;
            }else {
                // 图文条目
                ViewHolder holder = null;
                // 1.判断ConverView是否为空
                if (convertView == null){
                    convertView = View.inflate(getApplicationContext(),R.layout.list_process_item,null);
                    // 2.获取控件实例赋值给ViewHolder
                    holder = new ViewHolder();
                    holder.iv_icon_application = convertView.findViewById(R.id.iv_icon_application);
                    holder.tv_app_name = convertView.findViewById(R.id.tv_app_name);
                    holder.tv_memory = convertView.findViewById(R.id.tv_memory);
                    holder.cb_box = convertView.findViewById(R.id.cb_box);
                    // 3.将Holder放到ConverView上
                    convertView.setTag(holder);
                }else {
                    holder = (ViewHolder) convertView.getTag();
                }
                // 4.获取Holder中的控件实例，赋值
                holder.iv_icon_application.setBackground(getItem(position).getIcon());
                holder.tv_app_name.setText(getItem(position).getName());
                String strMemorySize = Formatter.formatFileSize(getApplicationContext(), getItem(position).getMemSize());
                holder.tv_memory.setText(strMemorySize);
                // 5.本进程无法被选中，所以先将CheckBox隐藏
                if ((getItem(position).getPackageName()).equals(getPackageName())){
                    holder.cb_box.setVisibility(View.GONE);
                }else {
                    holder.cb_box.setVisibility(View.VISIBLE);
                }
                holder.cb_box.setChecked(getItem(position).isCheck());
                // 6.返回现有条目填充上数据的View对象
                return convertView;
            }
        }
    }

    static class ViewHolder{
        ImageView iv_icon_application;
        TextView tv_app_name;
        TextView tv_memory;
        CheckBox cb_box;
    }

    static class ViewTitleHolder{
        TextView tv_title_des;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_process_manager);

        // 初始化UI
        initUI();

        // 初始化标题上的信息：进程总数，内存使用情况
        initTitleData();

        // 初始化ListView列表中的数据
        initListData();
    }

    /**
     * 初始化UI
     */
    private void initUI() {
        tv_process_count = findViewById(R.id.tv_process_count);
        tv_memory_info = findViewById(R.id.tv_memory_info);
        tv_title_type = findViewById(R.id.tv_title_type);
        lv_process_list = findViewById(R.id.lv_process_list);
        btn_all = findViewById(R.id.btn_all);
        btn_reverse = findViewById(R.id.btn_reverse);
        btn_clear = findViewById(R.id.btn_clear);
        btn_setting = findViewById(R.id.btn_setting);

        // 给ListView注册滚动事件
        lv_process_list.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                // 在滚动过程中调用方法
                if (mSystemList != null && mCustomerList != null){
                    if (firstVisibleItem >= mCustomerList.size() + 1){
                        // 滚动到了系统应用
                        tv_title_type.setText("系统进程("+mSystemList.size()+")");
                    }else {
                        // 滚动到了用户应用
                        tv_title_type.setText("用户进程("+mCustomerList.size()+")");
                    }
                }
            }
        });

        // 给ListView注册点击事件
        lv_process_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                if (position == 0 || position == mCustomerList.size() + 1){
                    // 纯文本条目
                    return;
                }else {
                    // 图文条目
                    if (position < mCustomerList.size() + 1){
                        // 用户应用
                        mProcessInfo = mCustomerList.get(position - 1);
                    }else {
                        // 系统应用
                        mProcessInfo = mSystemList.get(position - mCustomerList.size() - 2);
                    }
                    if (mProcessInfo != null){
                        if (!mProcessInfo.getPackageName().equals(getPackageName())){
                            // 选中条目指向的对象和本应用的包名不一致，才需要去取反状态和设置单选框状态
                            // 状态取反
                            mProcessInfo.setCheck(!mProcessInfo.isCheck());
                            // CheckBox显示状态取反
                            // 通过选中条目的view对象，findViewById找到此条目指向的cb_box，然后切换其状态
                            CheckBox cb_box = view.findViewById(R.id.cb_box);
                            cb_box.setChecked(mProcessInfo.isCheck());
                        }
                    }
                }
            }
        });

        btn_all.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 全选
                selectAll();
            }
        });

        btn_reverse.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 反选
                selectReverse();
            }
        });

        btn_clear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 一键清理内存
                clearAll();
            }
        });

        btn_setting.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setting();
            }
        });
    }

    /**
     * "设置"按钮的功能
     */
    private void setting() {
        Intent intent = new Intent(this, ProcessSettingActivity.class);
        startActivityForResult(intent,0);
    }

    /**
     * 从“设置”Activityt退出后的一些操作
     * @param requestCode
     * @param resultCode
     * @param data
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        // 通知数据适配器刷新
        if (mAdapter != null){
            mAdapter.notifyDataSetChanged();
        }
    }

    /**
     * "一键清理"按钮的功能
     */
    private void clearAll() {
        // 0.创建一个记录释放了多大空间的变量
        long totalReleaseSpace = 0;
        // 1.创建一个记录需要杀死的进程的集合
        List<ProcessInfo> killProcessList = new ArrayList<>();
        // 2.获取选中进程
        for (ProcessInfo processInfo : mCustomerList){
            if (processInfo.getPackageName().equals(getPackageName())){
                continue;
            }
            if (processInfo.isCheck()){
                // 3.记录被选中的用户进程（即需要杀死）
                killProcessList.add(processInfo);
            }
        }
        for (ProcessInfo processInfo : mSystemList){
            if (processInfo.isCheck()){
                // 4.记录被选中的系统进程（即需要杀死）
                killProcessList.add(processInfo);
            }
        }
        // 5.循环遍历killProcessList，然后移除mCustomerList和mSystemList中的对象
        for (ProcessInfo processInfo : killProcessList) {
            // 6.判断当前进程再哪个集合中，从所在集合中移除
            if (mCustomerList.contains(processInfo)){
                mCustomerList.remove(processInfo);
            }
            if (mSystemList.contains(processInfo)){
                mSystemList.remove(processInfo);
            }
            // 7.杀死记录在killProcessList中的进程
            ProcessInfoDao.killProcess(this,processInfo);
            // 8.记录释放控件的总大小
            totalReleaseSpace += processInfo.getMemSize();
        }
        // 9.在集合改变后，需要通知数据适配器刷新
        if (mAdapter != null){
            mAdapter.notifyDataSetChanged();
        }
        // 10.更新进程总数
        mProcessCount -= killProcessList.size();
        // 11.更新可用剩余空间（释放空间 + 原有剩余空间 = 当前剩余空间）
        mAvailSpace += totalReleaseSpace;
        // 12.根据进程总数和剩余空间大小更新控件
        tv_process_count.setText("进程总数："+mProcessCount);
        tv_memory_info.setText("剩余/总共" + Formatter.formatFileSize(this,mAvailSpace) + "/" + Formatter.formatFileSize(this,mTotalSpace));
        // 13.通过Toast告知用户，释放了多少空间，杀死多少进程（也可以使用C语言的占位符）
        ToastUtil.show(getApplicationContext(),"杀死了" + killProcessList.size() + "个进程，释放了" + Formatter.formatFileSize(this,totalReleaseSpace));
    }

    /**
     * “全选”按钮的功能
     */
    private void selectAll() {
        // 1.将所有集合中的对象上的isCheck字段设置为true代表全选（除了手机卫士自己）
        for (ProcessInfo processInfo : mCustomerList){
            if (processInfo.getPackageName().equals(getPackageName())){
                continue;
            }
            processInfo.setCheck(true);
        }
        for (ProcessInfo processInfo : mSystemList){
            processInfo.setCheck(true);
        }
        // 2.通知数据适配器刷新
        if (mAdapter != null){
            mAdapter.notifyDataSetChanged();
        }
    }

    /**
     * “反选”按钮的功能
     */
    private void selectReverse() {
        // 1.将所有集合中的对象上的isCheck字段设置为true代表全选（除了手机卫士自己）
        for (ProcessInfo processInfo : mCustomerList){
            if (processInfo.getPackageName().equals(getPackageName())){
                continue;
            }
            processInfo.setCheck(!processInfo.isCheck());
        }
        for (ProcessInfo processInfo : mSystemList){
            processInfo.setCheck(!processInfo.isCheck());
        }
        // 2.通知数据适配器刷新
        if (mAdapter != null){
            mAdapter.notifyDataSetChanged();
        }
    }

    /**
     * 初始化标题上的信息：进程总数，内存使用情况
     */
    private void initTitleData() {
        // 获取进程总数
        mProcessCount = ProcessInfoDao.getProcessCount(this);
        tv_process_count.setText("进程总数：" + mProcessCount);
        // 获取可用内存大小
        mAvailSpace = ProcessInfoDao.getAvailSpace(this);
        String strAvailSpace = Formatter.formatFileSize(this, mAvailSpace); // 格式化
        // 获取总内存大小
        mTotalSpace = ProcessInfoDao.getTotalSpace(this);
        String strTotalSpace = Formatter.formatFileSize(this, mTotalSpace); // 格式化
        tv_memory_info.setText("剩余/总共" + strAvailSpace + "/" + strTotalSpace);
    }

    /**
     * 初始化列表中的数据
     */
    private void initListData() {
        getData();
    }

    /**
     * 获取数据的方法
     */
    private void getData(){
        new Thread(){
            @Override
            public void run() {
                // 2.准备填充ListView中数据适配器的数据
                mProcessInfoList = ProcessInfoDao.getProcessInfoList(getApplicationContext());
                mSystemList = new ArrayList<>();
                mCustomerList = new ArrayList<>();
                // 分割集合
                for (ProcessInfo processInfo : mProcessInfoList) {
                    if (processInfo.isSystem()){
                        // 系统进程
                        mSystemList.add(processInfo);
                    }else {
                        // 用户进程
                        mCustomerList.add(processInfo);
                    }
                }
                // 3.发送空消息进行数据绑定
                mHandler.sendEmptyMessage(0);
            }
        }.start();
    }
}